package scanner

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/cnssl/cert-deploy-iis/internal/powershell"
)

// IISSiteInfo IIS 站点信息
type IISSiteInfo struct {
	SiteName       string `json:"SiteName"`
	State          string `json:"State"`
	HostName       string `json:"HostName"`
	Port           int    `json:"Port"`
	IP             string `json:"IP"`
	CertThumbprint string `json:"CertThumbprint"`
	CertSubject    string `json:"CertSubject"`
	CertIssuer     string `json:"CertIssuer"`
	CertExpires    string `json:"CertExpires"`
	CertDaysLeft   int    `json:"CertDaysLeft"`
}

// IISScanner IIS 配置扫描器
type IISScanner struct {
	runner *powershell.Runner
}

// NewIISScanner 创建 IIS 扫描器
func NewIISScanner() *IISScanner {
	return &IISScanner{
		runner: powershell.NewRunner(),
	}
}

// Scan 扫描所有 IIS SSL 站点
func (s *IISScanner) Scan() ([]IISSiteInfo, error) {
	// 调用 PowerShell 脚本列出所有站点
	output, err := s.runner.ListSites()
	if err != nil {
		return nil, fmt.Errorf("failed to list IIS sites: %w", err)
	}

	// 解析 JSON 输出
	var sites []IISSiteInfo
	if err := json.Unmarshal([]byte(output), &sites); err != nil {
		// 可能是单个对象而不是数组
		var site IISSiteInfo
		if err := json.Unmarshal([]byte(output), &site); err != nil {
			return nil, fmt.Errorf("failed to parse IIS sites JSON: %w", err)
		}
		sites = []IISSiteInfo{site}
	}

	return sites, nil
}

// PrintScanResult 打印扫描结果
func (s *IISScanner) PrintScanResult(sites []IISSiteInfo) {
	if len(sites) == 0 {
		fmt.Println("No SSL sites found in IIS.")
		return
	}

	fmt.Printf("Found %d SSL site(s) in IIS:\n\n", len(sites))

	for i, site := range sites {
		fmt.Printf("Site %d:\n", i+1)
		fmt.Printf("  Site Name:   %s\n", site.SiteName)
		fmt.Printf("  State:       %s\n", site.State)
		fmt.Printf("  Binding:     %s:%d (IP: %s)\n", site.HostName, site.Port, site.IP)

		if site.CertThumbprint != "" {
			fmt.Printf("  Certificate:\n")
			fmt.Printf("    Thumbprint: %s\n", site.CertThumbprint)
			fmt.Printf("    Subject:    %s\n", site.CertSubject)
			fmt.Printf("    Issuer:     %s\n", site.CertIssuer)

			if site.CertExpires != "N/A" {
				fmt.Printf("    Expires:    %s\n", site.CertExpires)

				if site.CertDaysLeft >= 0 {
					status := "OK"
					if site.CertDaysLeft < 7 {
						status = "CRITICAL"
					} else if site.CertDaysLeft < 15 {
						status = "WARNING"
					}
					fmt.Printf("    Days Left:  %d (%s)\n", site.CertDaysLeft, status)
				}
			}
		} else {
			fmt.Printf("  Certificate: None (SNI binding may be configured)\n")
		}

		fmt.Println()
	}
}

// GetSiteByName 根据站点名称获取站点信息
func (s *IISScanner) GetSiteByName(siteName string) (*IISSiteInfo, error) {
	sites, err := s.Scan()
	if err != nil {
		return nil, err
	}

	for _, site := range sites {
		if site.SiteName == siteName {
			return &site, nil
		}
	}

	return nil, fmt.Errorf("site not found: %s", siteName)
}

// GetSiteByHostname 根据主机名获取站点信息
func (s *IISScanner) GetSiteByHostname(hostname string) (*IISSiteInfo, error) {
	sites, err := s.Scan()
	if err != nil {
		return nil, err
	}

	for _, site := range sites {
		if strings.EqualFold(site.HostName, hostname) {
			return &site, nil
		}
	}

	return nil, fmt.Errorf("site not found for hostname: %s", hostname)
}

// GetCertificateExpiry 获取证书到期时间
func (s *IISScanner) GetCertificateExpiry(siteName string) (time.Time, error) {
	site, err := s.GetSiteByName(siteName)
	if err != nil {
		return time.Time{}, err
	}

	if site.CertExpires == "N/A" || site.CertExpires == "" {
		return time.Time{}, fmt.Errorf("no certificate found for site: %s", siteName)
	}

	// 解析时间 "2025-12-31 23:59:59"
	expiry, err := time.Parse("2006-01-02 15:04:05", site.CertExpires)
	if err != nil {
		return time.Time{}, fmt.Errorf("failed to parse expiry time: %w", err)
	}

	return expiry, nil
}

// GenerateConfigTemplate 生成配置模板建议
func (s *IISScanner) GenerateConfigTemplate(site IISSiteInfo) map[string]interface{} {
	template := map[string]interface{}{
		"version":     "1.0",
		"site_name":   site.SiteName,
		"enabled":     true,
		"server_type": "iis",
		"api": map[string]string{
			"url":      "https://api.example.com/auto/cert",
			"refer_id": "YOUR_REFER_ID_HERE",
		},
		"domains": []string{
			site.HostName,
		},
		"iis": map[string]interface{}{
			"site_name": site.SiteName,
			"hostname":  site.HostName,
			"port":      site.Port,
			"ip":        site.IP,
		},
		"schedule": map[string]int{
			"check_interval_hours": 12,
			"renew_before_days":    15,
		},
		"backup": map[string]interface{}{
			"enabled":       true,
			"keep_versions": 3,
		},
	}

	return template
}
